home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * MacZoop - "the framework for the rest of us"
- *
- *
- *
- * ZDialog.cpp -- a dialog box
- *
- *
- *
- *
- *
- * © 1996, Graham Cox
- *
- *
- *
- *
- *************************************************************************************************/
-
-
- #include "ZDialog.h"
- #include "MacZoop.h"
- #include "ZGrafState.h"
-
- #include <dialogs.h>
- #include <palettes.h>
- #include <fp.h>
-
- // static method and global UPP to handle user items in dialogs in a general
- // object-oriented fashion. Hey- cool feature!
-
- static pascal void UserItemVectorProc(DialogPtr theDialog, short item);
- UserItemUPP gUIVectorUPP = NewUserItemProc(UserItemVectorProc);
-
-
- CLASSCONSTRUCTOR( ZDialog );
-
- /*-------------------------------*** CONSTRUCTOR ***----------------------------------*/
-
-
- ZDialog::ZDialog( ZCommander* aBoss, const short dialogID )
- : ZWindow( aBoss, dialogID )
- {
- classID = CLASS_ZDialog;
-
- isModal = FALSE; // set up by MakeMacWindow
- isInline = FALSE; // set up by RunModal.
- dItemInfo = NULL;
- ictb = NULL;
- signalDismiss = 0;
- exitItem = 0;
- baseItems = 0;
- }
-
-
- ZDialog::ZDialog()
- : ZWindow()
- {
- classID = CLASS_ZDialog;
-
- isModal = FALSE; // set up by MakeMacWindow
- isInline = FALSE; // set up by RunModal.
- dItemInfo = NULL;
- ictb = NULL;
- signalDismiss = 0;
- exitItem = 0;
- baseItems = 0;
- }
-
-
- /*---------------------------------*** DESTRUCTOR ***----------------------------------*/
-
-
- ZDialog::~ZDialog()
- {
- if ( dItemInfo )
- {
- // make sure any allocated mirror TERecords are disposed of:
-
- short i = CountDITL( macWindow );
- unsigned short flags;
- TEHandle th;
- long max;
-
- while( i )
- {
- GetEditFieldInfo( i--, &flags, (long*) &th, &max );
-
- if (( flags & editFieldHCMirrorAlloc ) && ( th != NULL ))
- TEDispose( th );
- }
-
- DisposeHandle((Handle) dItemInfo );
- }
-
- if ( ictb )
- DisposeHandle((Handle) ictb );
-
- if ( macWindow )
- {
- // save off position in prefs if this feature enabled. No point doing it if the
- // dialog is not a moveable type:
-
- #if _AUTO_WPOS_FOR_DIALOGS
-
- short wVar = GetWVariant( macWindow );
-
- if ( !isModal || wVar == movableDBoxProc )
- SavePosition();
-
- #endif
-
- if ( MacHasDM())
- RemoveDragHandlers();
-
- DisposeDialog( macWindow );
- }
-
- macWindow = NULL;
- }
-
- /*-------------------------------*** INITZWINDOW ***----------------------------------*/
- /*
-
- construct the dialog and set it up
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::InitZWindow()
- {
- MakeMacWindow( windID ); // make the dialog box, and set modal flag
-
- if ( MacHasDM())
- InstallDragHandlers();
-
- short item = baseItems = CountDITL( macWindow );
-
- // set up the handle which is a list of DItemInfo records (1 for every dialog item)
-
- FailNIL( dItemInfo = ( DItemInfoHdl ) NewHandleClear( sizeof( DItemInfo ) * item ));
-
- SetUpUserItems(); // install user item procs so we get callbacks
- SetUpRadioGroups(); // automatically deal with radio button groups
- Focus(); // make sure dialog is focussed for setup call
- SetUp(); // call user's set up method
- OutlineDefaultItem(); // set default button to ok button
- DisableItem( 0 ); // initially disable everything- will be reset correctly by
- // initial activate event
-
- // tell the window manager of our existence. This must be done after the
- // full build of the mac window since the window manager needs to get
- // information from it. Thus if you override this method, make sure you
- // make the same call.
-
- gWindowManager->AddWindow( this );
- ResetAlertStage();
-
- // restore position if this feature enabled:
- // n.b. does nothing at all if no stored position or no file available, so safe to call
- // regardless.
-
- #if _AUTO_WPOS_FOR_DIALOGS
- RestorePosition();
- #endif
- }
-
-
- /*------------------------------*** MAKEMACWINDOW ***---------------------------------*/
- /*
-
- make a dialog. This tries to construct a dialog using a 'DLOG' resource with the ID
- passed. The refcon is set to this object, so do not use it. Sets the modal flag too.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::MakeMacWindow( const short dialogID )
- {
- // create the macintosh dialog:
-
- FailNILRes( macWindow = GetNewDialog( dialogID, NULL, (WindowPtr) -1L ));
-
- // set our refcon to point to the object. DO NOT USE THE REFCON!
-
- SetWRefCon( macWindow, (long) this );
-
- // see whether this is modal or not by examining the style of the window. This
- // flag affects the way commands are processed.
-
- short wVar = GetWVariant( macWindow );
-
- isModal = ( wVar == dBoxProc ||
- wVar == plainDBox ||
- wVar == altDBoxProc ||
- wVar == movableDBoxProc );
-
- // note that dialogs should normally not set the <isFloating> member, since the window
- // manager knows that dialogs should go in front of floaters anyway. If you use a dialog as
- // a floating window, note that it won't get the menubar and keyboard focus, so you should
- // avoid the use of editable text fields, etc. Though no-one's enforcing any of this, it
- // is bad human interface to have type-in fields in floating windows.
-
- // look for any associated 'ictb' resource and keep a local copy. If not a colour dialog,
- // don't bother with this since only colour dialogs support this feature.
-
- if ( IsColourPort( macWindow ))
- {
- ictb = ( ictbHandle ) GetResource( 'ictb', dialogID );
-
- if ( ictb )
- {
- DetachResource((Handle) ictb );
- HNoPurge((Handle) ictb );
- }
- }
- }
-
-
- /*------------------------------*** MAKEMACWINDOW ***---------------------------------*/
-
-
- void ZDialog::MakeMacWindow( Rect* aRect, Str255 title, Boolean visible, short varCode, Boolean hasCloseBox, void* userData )
- {
- if ( gMacInfo.supportsColour )
- FailNIL( macWindow = NewColorDialog( NULL, aRect, title, visible, varCode, (WindowPtr) -1L, hasCloseBox, 0, (Handle) userData ));
- else
- FailNIL( macWindow = NewDialog( NULL, aRect, title, visible, varCode, (WindowPtr) -1L, hasCloseBox, 0, (Handle) userData ));
-
- SetWRefCon( macWindow, (long) this );
- CopyPString( title, macFile.name );
-
- isModal = ( varCode == dBoxProc ||
- varCode == plainDBox ||
- varCode == altDBoxProc ||
- varCode == movableDBoxProc );
- }
-
-
- /*-----------------------------*** SETUPUSERITEMS ***---------------------------------*/
- /*
-
- make every user item point to our vector proc for handling these items. Then you can
- simply override DrawUserItem to draw anything you want in the dialog!
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetUpUserItems( short fromItemNo )
- {
- short item, itemType;
- Handle itemHand;
- Rect itemBox;
-
- item = CountDITL( macWindow );
-
- while( item > fromItemNo )
- {
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & 0x7F ) == userItem )
- SetDialogItem( macWindow, item, itemType, (Handle) gUIVectorUPP, &itemBox );
-
- item--;
- }
- }
-
-
-
- /*-----------------------------------*** DRAW ***-------------------------------------*/
- /*
- draws the dialog items
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Draw()
- {
- SetDefaultColours();
- UpdateDialog( macWindow, macWindow->visRgn );
-
- // we also need to correctly draw any disabled edit fields which require that
- // the local DrawUserItem code is called to correctly maintain the disabled appearance.
-
- unsigned short iFlags;
- short i = CountDITL( macWindow );
- short iType;
-
- while ( i )
- {
- iType = GetItemType( i ) & 0x7F;
-
- if ( iType == statText )
- {
- GetEditFieldInfo( i, &iFlags );
-
- if ( iFlags & editFieldIsDisabled )
- ZDialog::DrawUserItem( i );
- }
- i--;
- }
-
- #ifdef _GREYSCALE_APPEARANCE
- AddGreyscaleEffects();
- #endif
-
- OutlineDefaultItem();
- }
-
-
- /*-------------------------------*** DRAWONEITEM ***----------------------------------*/
- /*
- redraws a single item immediately. Call if something needs a quick update in the dialog.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DrawOneItem( const short item )
- {
- ZGrafState gs;
- Rect iBox;
- RgnHandle udRgn;
-
- Focus();
- GetItemBounds( item, &iBox );
- udRgn = NewRgn();
- RectRgn( udRgn, &iBox );
-
- UpdateDialog( macWindow, udRgn );
- SetClip( udRgn );
- DisposeRgn( udRgn );
-
- #ifdef _GREYSCALE_APPEARANCE
- AddGreyscaleEffects();
- #endif
- }
-
-
- /*-----------------------------*** SETDIALOGBASEFONT ***------------------------------*/
- /*
- sets the default font for the dialog if 12 point chicago is not your bag. This affects
- only static and editable text items. This changes all such items in the dialog- if
- you need to set it on an individual item basis, use the 'ictb' mechanism. Call this once
- after InitZWindow(), but before dialog is selected.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetDialogBaseFont( short fontID, short fontSize, short fontStyle )
- {
- Focus();
- TextFont( fontID );
- TextFace( fontStyle );
- TextSize( fontSize );
-
- // set the same parameters in the textEdit record
-
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( dp->textH )
- {
- (*dp->textH)->txFont = fontID;
- (*dp->textH)->txFace = fontStyle;
- (*dp->textH)->txSize = fontSize;
-
- FontInfo fi;
-
- GetFontInfo( &fi );
-
- (*dp->textH)->fontAscent = fi.ascent;
- (*dp->textH)->lineHeight = fi.ascent + fi.descent + fi.leading;
-
- TECalText( dp->textH );
- }
- }
-
-
- /*-----------------------------------*** CLICK ***------------------------------------*/
- /*
- handle clicks in the dialog, This determines the item and calls ClickItem.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Click( const Point mouse, const short modifiers )
- {
- DialogPeek dp = ( DialogPeek ) macWindow;
-
- // which item was hit?
-
- short item = FindDialogItem( macWindow, mouse ) + 1;
-
- // if the item is enabled, call TrackControl, TEClick, etc as needed.
-
- if ( item > 0 )
- {
- short iType, partCode;
- Handle iHand;
- Rect iBox;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
-
- // if the item is a control, track it. Call ClickItem if control clicked and
- // item was enabled and not unhilited.
-
- if (iType & ctrlItem )
- {
- if ((*(ControlHandle) iHand )->contrlHilite != 255 )
- {
- partCode = TrackControl((ControlHandle) iHand, mouse, ( ControlActionUPP ) -1L );
-
- if (( partCode != 0 ) && (( iType & 0x80 ) == 0 ))
- {
- // if a button, set the local zoom source rect
-
- if ( iType == ( btnCtrl + ctrlItem ))
- {
- GrafPtr savePort;
-
- GetPort( &savePort );
- SetPort( macWindow );
-
- SetLocalZoomSource( &iBox );
-
- SetPort( savePort );
- }
-
- ClickItem( item );
- }
- }
- }
- else
- {
- if ( iType & editText )
- {
- // if an edit field, pass click to text edit. If not in the current
- // field, switch fields to the one clicked.
-
- ZGrafState zg;
-
- if ( item != dp->editField + 1)
- SelectItem (item );
-
- SetTEItemDataFromIctb( item, TRUE );
- TEClick( mouse, (modifiers & shiftKey) == shiftKey , dp->textH );
- }
-
- // all enabled items are passed to ClickItem
-
- if (( iType & 0x80 ) == 0 )
- ClickItem( item );
- }
- }
-
- // see if any user action resulted in a request to dismiss the dialog. This is quite common-
- // e.g. a double-click in a list, etc. To close safely, we need to action this right at the end
- // of processing a click. To work this, set signalDismiss to ok or cancel in response to your
- // action- do not call Close directly or things may not work as you expect, or worse, crash.
-
- if (( item != ok ) && ( item != cancel ) && ( signalDismiss > 0 ))
- FakeClick( signalDismiss );
- }
-
-
- /*---------------------------------*** ACTIVATE ***-----------------------------------*/
- /*
- activates TextEdit if present
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Activate()
- {
- if ( macWindow )
- {
- Focus();
-
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( HasEditFields())
- {
- ZGrafState zg;
-
- SetTEItemDataFromIctb( dp->editField + 1 , TRUE );
- TEActivate( dp->textH );
- }
-
- EnableItem( 0 );
- }
-
- ZWindow::Activate();
- }
-
-
- /*--------------------------------*** DEACTIVATE ***----------------------------------*/
- /*
- deactivates TextEdit if present
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Deactivate()
- {
- ZWindow::Deactivate();
-
- if ( macWindow )
- {
- Focus();
- DisableItem( 0 );
-
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( HasEditFields())
- {
- ZGrafState zg;
-
- SetTEItemDataFromIctb( dp->editField + 1 , TRUE );
- TEDeactivate( dp->textH );
- }
- }
- }
-
-
- /*-----------------------------------*** IDLE ***-------------------------------------*/
- /*
- blink TextEdit cursor if present
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Idle()
- {
- if ( macWindow )
- {
- Focus();
-
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( HasEditFields())
- {
- ZGrafState zg;
-
- SetTEItemDataFromIctb( dp->editField + 1 , TRUE );
- TEIdle( dp->textH );
- }
- }
- }
-
-
- /*-----------------------------------*** TYPE ***-------------------------------------*/
- /*
- pass TextEdit the typed character if present. If tab key, cycle through fields
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Type( const char theKey, const short modifiers )
- {
- if ( macWindow )
- {
- DialogPeek dp = (DialogPeek) macWindow;
- short iType;
- Handle iHand;
- Rect iBox;
-
- Focus();
-
- if ( HasEditFields())
- {
- if ( theKey == TAB_KEY ) // tab
- {
- short nextField, fMax;
- Boolean reverseTab;
-
- reverseTab = ( modifiers & shiftKey ) == shiftKey;
-
- // find the next edit field item that can be set
-
- if ( reverseTab )
- nextField = dp->editField;
- else
- nextField = dp->editField + 2;
-
- fMax = CountDITL( macWindow );
-
- do
- {
- if ( nextField < 1 )
- nextField = fMax;
-
- if ( nextField > fMax )
- nextField = 1;
-
- // if we got back to where we started, so nothing. This will occur
- // if the dialog has only 1 edit field
-
- if ( nextField == dp->editField + 1 )
- return;
-
- GetDialogItem( macWindow, nextField, &iType, &iHand, &iBox );
-
- // if this is an edit field, then select that one
-
- if (( iType & 0x7F ) == editText && ( iBox.left < 8192 ))
- {
- SelectItem( nextField );
- break;
- }
-
- if ( reverseTab )
- nextField--;
- else
- nextField++;
- }
- while( 1 );
- }
- else
- {
- if ( dp->textH )
- {
- // if the field being targetted has some special flags set such as
- // numeric only, etc, this is where we enforce it. Keys that are illegal
- // according to the field's flags result in a beep and are not passed
- // on to the TextEdit record.
-
- char k = theKey;
-
- if ( KeyIsLegal( &k, dp->editField + 1 ))
- {
- // return, enter and escape are never passed to the field, but are
- // not treated as "illegal" as such...
-
- if ( theKey != RETURN_KEY &&
- theKey != ENTER_KEY &&
- theKey != ESCAPE_KEY )
- {
- ZGrafState zg;
- unsigned short f;
- TEHandle th;
- long mx;
-
- SetTEItemDataFromIctb( dp->editField + 1, TRUE );
- TEKey( k, dp->textH );
-
- // if the field is a password field, echo the true character
- // to the field's mirror.
-
- GetEditFieldInfo( dp->editField + 1, &f, (long*) &th, &mx );
-
- if (( f & editFieldHCMirrorAlloc ) && ( th != NULL ))
- {
- (*th)->selStart = (*dp->textH)->selStart;
- (*th)->selEnd = (*dp->textH)->selEnd;
- TEKey( theKey, th );
- }
- }
- }
- else
- SysBeep( 1 );
- }
- }
-
- ClipRect( &macWindow->portRect );
-
- // if item is enabled, call ClickItem too
-
- GetDialogItem( macWindow, dp->editField + 1, &iType, &iHand, &iBox );
-
- if (( iType & 0x80 ) == 0 )
- ClickItem( dp->editField + 1 );
- }
- }
- }
-
-
-
- /*------------------------------*** DRAWUSERITEM ***----------------------------------*/
- /*
-
- this is called to update each user item in the dialog. You can override this to draw
- custom dialog items. The default method draws a 50% grey outline around the item.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DrawUserItem( const short item )
- {
- short itemType, p;
- Handle itemHand;
- Rect itemBox;
- RgnHandle clipAbove, temp;
- ZGrafState gs;
-
- // as a real service to programmers, we clip out all items from the dialog with IDs
- // lower than this user item. This allows us to define a border that intersects other
- // items and we don't need to worry about whether it will draw over them- it won't.
-
- clipAbove = NewRgn();
- temp = NewRgn();
-
- for( p = 1; p < item; p++ )
- {
- GetItemBounds( p, &itemBox );
- RectRgn( temp, &itemBox );
- UnionRgn( clipAbove, temp, clipAbove );
- }
-
- GetClip( temp );
- DiffRgn( temp, clipAbove, temp );
- SetClip( temp );
-
- DisposeRgn( clipAbove );
- DisposeRgn( temp );
-
- // ok, now draw this item...
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- // if the background of the window is not white, and the compiler flag is
- // set, draw a 3D effect line instead of a 50% gray one.
-
- #ifdef _GREYSCALE_APPEARANCE
-
- // if the item is a disabled edit field, grey out the text and draw a grey border
-
- unsigned short iFlags;
-
- GetEditFieldInfo( item, &iFlags );
- AuxWinHandle awH;
- RGBColor rc;
- GDHandle gdH;
-
- if ((( itemType & 0x7F ) == statText ) && ( iFlags & editFieldIsDisabled ))
- {
- SetTEItemDataFromIctb( item, TRUE );
- PenMode( patBic );
- PenPat( &qd.gray );
- PaintRect( &itemBox );
- PenNormal();
- InsetRect( &itemBox, -3, -3 );
- rc.red = rc.green = rc.blue = 0x7F7F; // mid grey
- RGBForeColor( &rc );
- }
- else
- {
- if ( IsColourPort( macWindow) && GetAuxWin( macWindow, &awH ))
- {
- Rect gib;
- RGBColor rgbContent;
-
- gib = itemBox;
- LocalToGlobal( &topLeft( gib ));
- LocalToGlobal( &botRight( gib ));
- gdH = GetMaxDevice( &gib );
-
- rgbContent = (*(*awH)->awCTable)->ctTable[0].rgb;
- rc.red = rc.green = rc.blue = 0xFFFF;
-
- GetGray( gdH, &rgbContent, &rc );
-
- RGBForeColor( &rc );
- OffsetRect( &itemBox, 1, 1 );
- FrameRect( &itemBox );
- OffsetRect( &itemBox, -1, -1 );
-
- rc.red = rc.green = rc.blue = 0;
- GetGray( gdH, &rgbContent, &rc );
- RGBForeColor( &rc );
- }
- else
- {
- PenNormal();
- PenPat( &qd.gray );
- PenSize( 1,1 );
- }
- }
- FrameRect( &itemBox );
-
- #else
-
- PenNormal();
- PenPat( &qd.gray );
- PenSize( 1,1 );
-
- // if the item is a disabled edit field, grey out the text and draw a grey border
-
- unsigned short iFlags;
-
- GetEditFieldInfo( item, &iFlags );
-
- if ((( itemType & 0x7F ) == statText ) && ( iFlags & editFieldIsDisabled ))
- {
- PenMode( patBic );
- PaintRect( &itemBox );
- PenMode( patCopy );
- InsetRect( &itemBox, -3, -3 );
- }
-
- FrameRect( &itemBox );
-
- #endif
- }
-
-
- /*----------------------------------*** DOCUT ***-------------------------------------*/
- /*
- handle edit command cut.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoCut()
- {
- DialogCut( macWindow );
- gClipboard->Clear();
-
- FailOSErr( TEToScrap());
- }
-
-
- /*----------------------------------*** DOCOPY ***------------------------------------*/
- /*
- handle edit command copy.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoCopy()
- {
- DialogCopy( macWindow );
- gClipboard->Clear();
- FailOSErr( TEToScrap());
- }
-
-
- /*---------------------------------*** DOPASTE ***------------------------------------*/
- /*
- handle edit command paste.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoPaste()
- {
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( PasteDataIsLegal( dp->editField + 1 ))
- {
- FailOSErr( TEFromScrap());
- SetTEItemDataFromIctb( dp->editField + 1, TRUE );
- DialogPaste( macWindow );
- }
- else
- SysBeep( 1 );
- }
-
-
- /*---------------------------------*** DOCLEAR ***------------------------------------*/
- /*
- handle edit command clear.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoClear()
- {
- DialogDelete( macWindow );
- }
-
-
- /*-------------------------------*** DOSELECTALL ***----------------------------------*/
- /*
- handle edit command select all by hiliting all text in current field.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoSelectAll()
- {
- DialogPeek dp = (DialogPeek) macWindow;
- SelectDialogItemText( macWindow, dp->editField + 1, 0, 32767 );
- }
-
- /*-------------------------------*** UPDATEMENUS ***----------------------------------*/
- /*
- enable the edit menu items if we have edit fields
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::UpdateMenus()
- {
- // enable cut, copy, clear IF we have edit fields. If modal,
- // do NOT pass this on up the chain.
-
- if ( HasEditFields())
- {
- gMenuBar->EnableCommand( kCmdCut );
- gMenuBar->EnableCommand( kCmdCopy );
- gMenuBar->EnableCommand( kCmdClear );
- gMenuBar->EnableCommand( kCmdSelectAll );
-
- if ( CanPasteType())
- gMenuBar->EnableCommand( kCmdPaste );
- }
-
- if ( !isModal )
- ZWindow::UpdateMenus();
- }
-
-
- /*-------------------------------*** CANPASTETYPE ***---------------------------------*/
- /*
- we can paste if we have edit fields and there is text on the clipboard
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::CanPasteType()
- {
- return ( HasEditFields() && gClipboard->QueryType( 'TEXT' ));
- }
-
-
- /*----------------------------------*** SETUP ***-------------------------------------*/
- /*
-
- called when the dialog is built so you can initialise your dialog items. For user items,
- override DrawUserItem rather than installing your own procs here. By default, this hilites
- the text of the first edit field it finds.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetUp()
- {
- // set the first edit field to be hilited
-
- short i, iType, items = CountDITL( macWindow );
- Handle iHand;
- Rect iBox;
-
- for ( i = 1; i <= items; i++ )
- {
- GetDialogItem( macWindow, i, &iType, &iHand, &iBox );
-
- if (( iType & 0x7F ) == editText )
- {
- SelectItem( i );
- break;
- }
- }
- // override this method to initialise your controls, etc to the desired
- // state for your dialog, but call the inherited method as well.
-
- long id = (long) windID << 16;
-
- SendMessage( kMsgDialogSetUp, &id );
- }
-
-
- /*-----------------------------*** ADJUSTCURSOR ***-----------------------------------*/
- /*
-
- overrides ZWindow to set the cursor to an i-beam over edit fields.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::AdjustCursor( const Point mouse, const short modifiers )
- {
- short item, itemType;
- Handle itemHand;
- Rect itemBox;
-
- item = FindItem( mouse );
-
- if ( item > 0 )
- {
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & 0x7F ) == editText )
- {
- PauseCursorAnimation( iBeamCursor );
- return;
- }
- }
-
- ZWindow::AdjustCursor( mouse, modifiers );
- }
-
-
- /*--------------------------------*** CLICKITEM ***-----------------------------------*/
- /*
-
- an enabled item was clicked (or an enabled field was typed in) This handles check boxes
- by toggling their state, and OK and Cancel buttons in modal dialogs. It also now handles
- groups of radio buttons. Override to handle clicks in other dialog items, but call the
- inherited method to deal with these standard items.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ClickItem( const short theItem )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- GetPort( &savePort );
- SetPort( macWindow );
-
- // get info about the item clicked
-
- GetDialogItem( macWindow, theItem, &itemType, &itemHand, &itemBox );
-
- // if a checkbox, toggle its state
-
- if (( itemType & 0x7F ) == ( ctrlItem + chkCtrl ))
- SetControlValue(( ControlHandle ) itemHand, GetControlValue(( ControlHandle ) itemHand ) ^ 1 );
-
- // if the item is a radio button, handle it if it is part of a group
-
- if (( itemType & 0x7F ) == ( ctrlItem + radCtrl ))
- {
- // check that the control is actually enabled
-
- if ((*( ControlHandle ) itemHand )->contrlHilite != 255 )
- HandleRButtonGroupClick( theItem );
- }
- // if it is the OK or cancel button, dismiss the dialog if a modal dialog.
-
- if ((( theItem == ok ) || ( theItem == cancel )) &&
- (( itemType & 0x7F ) == ( ctrlItem + btnCtrl )) &&
- isModal )
- {
- exitItem = theItem;
-
- if ( theItem == ok )
- Close( kRunning ); // verifies dialog
- else
- {
- dirty = FALSE; // suppress save check
- SendMessage( kMsgDialogCancelled, &windID );
- ZWindow::Close( kRunning ); // does not verify dialog
- }
- }
- else
- {
- // for other items, send a message about the click. This allows a dialog's boss
- // to implement dialog features without needing to override the dialog itself
- // for simpler types of dialog. <msgData> is dialog ID in high word, and item
- // ID in low word of pointer to long.
-
- long di = ((long) windID << 16 ) | theItem;
- SendMessage( kMsgDialogItemClicked, &di );
- }
-
- SetPort( savePort );
- }
-
-
- /*---------------------------------*** RUNMODAL ***-----------------------------------*/
- /*
- Handle events until OK/Cancel is clicked. Do not abuse this method! Normally you should
- let dialogs work modelessly (even if modal) and not create dialogs "inline". For some
- simple cases it is convenient to create inline dialogs, in which case you can call this to
- implement a holding loop which returns TRUE for OK, FALSE for Cancel. This will return
- immediately for non-modal dialogs
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::RunModal()
- {
- Boolean okClicked = FALSE;
- ZDialog* topDialog;
-
- if ( isModal )
- {
- isInline = TRUE; // caller is responsible for deleting this
-
- // The recommended way to do simple dialogs is to wait for the kMsgDialogSuccessfullyClosed
- // message in the dialog's boss and respond there, or else subclass ZDialog to implement the
- // relevant actions/processing there. The inline technique should only be considered for
- // the simplest of dialogs, e.g. those that request a user parameter to a following function.
-
- do
- {
- gApplication->Process1Event();
- topDialog = (ZDialog*) gApplication->GetFrontWindow();
- }
- while(( topDialog == this ) && IsVisible());
-
- okClicked = ( exitItem == ok );
- }
-
- return okClicked;
- }
-
-
- /*-------------------------------*** DISMISSMODAL ***---------------------------------*/
- /*
- Force a modal dialog session to end by passing it a dismissal code (either "ok" or
- "cancel". This calls ClickItem on that item, hence triggering the dialog dismissal. This
- is very rarely needed- you are discouraged from using this to get rid of dialogs- normally
- they will look after themselves without explicit coding for dismissal.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DismissModal( const short itemDismiss )
- {
- if ( isModal )
- FakeClick( itemDismiss );
- }
-
-
- /*-------------------------------*** CLOSEDIALOG ***----------------------------------*/
- /*
-
- the dialog is about to close. You can abort the close by returning FALSE. Override to
- read the values of controls, other items, etc.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::CloseDialog()
- {
- // the dialog is about to close. Return FALSE if you can't close (Verify fields?)
- // we check if there are any fields that have limits set and are some kind of
- // numeric field. If the limits have been exceeded by the user's entry, we
- // hilite the offending field, make a noise and prevent the dialog from closing.
-
- if ( HasEditFields())
- {
- short item;
-
- item = CountDITL( macWindow );
-
- while( item )
- {
- if ( ! ValidateItem( item, TRUE ))
- return FALSE;
-
- item--;
- }
- }
-
- SendMessage( kMsgDialogSuccessfullyClosed, &windID );
-
- return TRUE;
- }
-
-
- /*----------------------------------*** CLOSE ***-------------------------------------*/
- /*
-
- overrides ZWindow so that closing the dialog correctly maintains the chain of command.
- This is called when a modeless dialog is closed from the Close menu, or go-away box, or
- when OK was clicked in a modal dialog.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::Close( const short phase )
- {
- // called for a modeless dialog. This calls CloseDialog. If TRUE, the object is
- // deleted. This overrides the similar method in ZWindow.
-
- Boolean wasClosed = CloseDialog();
-
- if ( wasClosed )
- {
- // if the dialog is inline, the caller is responsible for deleting it. In which case
- // we simply hide ourselves and will get deleted later.
-
- if ( isInline )
- Hide();
- else
- ZWindow::Close( phase );
- }
-
- return wasClosed;
- }
-
-
- /*-------------------------------*** VALIDATEITEM ***---------------------------------*/
- /*
-
- For an edit field item, this validates that the contents are acceptable within any
- constraints that may be set for the field, returning TRUE if OK, FALSE otherwise. For
- other types of item, this always returns TRUE. Called by CloseDialog(), but you can
- call it at any time you need to check the bounds of a field. If <showAlert> is TRUE,
- this also reports the bounds limits to the user if validation fails.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::ValidateItem( const short item, Boolean showAlert )
- {
- short iType;
- Boolean result = TRUE;
- unsigned short iFlags;
- long val, min, max;
-
- iType = GetItemType( item ) & 0x7F;
-
- if ( iType == editText )
- {
- GetEditFieldInfo( item, &iFlags, &min, &max );
-
- // is this some kind of limiting field?
-
- if ( iFlags & ( editFieldHasMinValue + editFieldHasMaxValue ) && ( iFlags & editFieldIsDisabled ) == 0 )
- {
- // it's a limiting field, so check the limits. The field is assumed to
- // contain some kind of integer value- other flags must be set to
- // ensure that the user can't type bad characters here.
-
- val = GetValue( item );
-
- if ((( iFlags & editFieldHasMinValue ) && ( val < min )) ||
- (( iFlags & editFieldHasMaxValue ) && ( val > max )))
- {
- // limits violated, so prevent closure
- // set up the wording of the alert...
-
- result = FALSE;
-
- if ( showAlert )
- {
- Str15 ma, mb;
- Str32 sa, sb;
-
- NumToString( min, ma );
- NumToString( max, mb );
-
- if (( iFlags & ( editFieldHasMinValue + editFieldHasMaxValue )) ==
- ( editFieldHasMinValue + editFieldHasMaxValue ))
- {
- GetIndString( sa, 128, 14 );
- GetIndString( sb, 128, 15 );
- }
- else
- {
- sb[0] = 0;
- mb[0] = 0;
-
- if ( iFlags & editFieldHasMinValue )
- GetIndString( sa, 128, 12 );
- else
- {
- GetIndString( sa, 128, 13 );
- NumToString( max, ma );
- }
- }
-
- ParamText( sa, ma, sb, mb );
- NotifyAlert( kFieldRangeAlertID );
- }
- else
- SysBeep( 1 );
-
- // set the value in the field to a legal one...
- SetValue( item, MIN( MAX( val, min ), max ));
- SelectItem( item );
- }
- }
- }
-
- return result;
- }
-
-
- /*---------------------------------*** FILTER ***-------------------------------------*/
- /*
-
- now's your chance! This allows you to examine and modify the event that is going to come to
- this dialog before the dialog manager gets it. By default, this maps return and enter keys
- to the dialog buttons. If the event is fully handled, return TRUE, else FALSE. If TRUE is
- returned, no further processing will occur.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::Filter( EventRecord* theEvent )
- {
- char theKey;
- Boolean fullyHandled = FALSE;
- short itemType;
- Handle itemHand;
- Rect itemBox;
- Boolean cmdPeriod;
-
- // see if command-period is down
-
- cmdPeriod = ((theEvent->what == keyDown) &&
- isModal &&
- ((theEvent->modifiers & cmdKey) == cmdKey ) &&
- ((theEvent->message & charCodeMask) == '.'));
-
- // map return, enter and escape keys to ok and cancel
-
- if ( theEvent->what == keyDown )
- {
- theKey = theEvent->message & charCodeMask;
-
- if (theKey == RETURN_KEY || // return
- theKey == ENTER_KEY) // enter
- {
- // make sure that item 1 is an enabled button
-
- GetDialogItem( macWindow, ok, &itemType, &itemHand, &itemBox );
-
- if ( itemType == ( ctrlItem + btnCtrl ) &&
- (*(ControlHandle) itemHand)->contrlHilite != 255 )
- {
- FakeClick( ok );
- fullyHandled = TRUE;
- }
- }
-
- if (( theKey == ESCAPE_KEY ) || cmdPeriod ) // escape or command-period
- {
- // make sure item 2 is an enabled button
-
- GetDialogItem( macWindow, cancel, &itemType, &itemHand, &itemBox );
-
- if ( itemType == ( ctrlItem + btnCtrl ) &&
- (*(ControlHandle) itemHand)->contrlHilite != 255 )
- {
- FakeClick( cancel );
- fullyHandled = TRUE;
- }
- }
- }
-
- return fullyHandled;
- }
-
-
- /*---------------------------------*** FAKECLICK ***----------------------------------*/
- /*
- fake a click on an item (presumably a button).
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::FakeClick( const short item )
- {
- GrafPtr savePort;
- Rect iBox;
-
- GetItemBounds( item, &iBox );
-
- GetPort( &savePort );
- SetPort( macWindow );
-
- HiliteItem( item, 1 );
- MZDelay( 8 );
- HiliteItem( item, 0 );
-
- SetLocalZoomSource( &iBox );
- SetPort( savePort );
-
- ClickItem( item );
- }
-
-
- /*--------------------------------*** GETITEMTYPE ***---------------------------------*/
- /*
- return the type of the item with ID passed.
- ----------------------------------------------------------------------------------------*/
-
- short ZDialog::GetItemType( const short item )
- {
- short iType;
- Handle iHand;
- Rect iRect;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iRect );
-
- return iType;
- }
-
-
- /*--------------------------------*** SETVALUE ***------------------------------------*/
- /*
-
- sets the value of the dialog item to <value>. This determines the type of the item and
- does the obvious thing. Various data types are accepted by overloading the parameters,
- though for controls, the value must be between -32767 and +32768 or an exception is thrown.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetValue(const short item, const long value)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- // for controls: check that parameter is within range, then set the control value
-
- if (( itemType & ctrlItem ) == ctrlItem )
- {
- if ( value < -32767 || value > 32768 )
- FailOSErr( paramErr );
- else
- SetControlValue(( ControlHandle ) itemHand, value );
- }
- else
- {
- // for text items: convert long to string, and set item text
-
- if ( itemType & ( editText | statText ))
- {
- Str255 iText;
-
- NumToString( value, iText );
- SetDialogItemText( itemHand, iText );
- }
- }
- }
-
-
- /*--------------------------------*** SETVALUE ***------------------------------------*/
-
- void ZDialog::SetValue( const short item, const Str255 value )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if ( itemType & ( editText | statText ))
- SetDialogItemText( itemHand, value );
- }
-
-
- /*--------------------------------*** SETVALUE ***------------------------------------*/
-
- void ZDialog::SetValue( const short item, const double value )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & ctrlItem ) == ctrlItem )
- {
- SetValue( item, (long) value );
- }
- else
- {
- if ( itemType & ( editText | statText ))
- {
- Str255 iText;
-
- RealToString( value, iText );
- SetDialogItemText( itemHand, iText );
- }
- }
- }
-
- /*--------------------------------*** GETVALUE ***------------------------------------*/
- /*
-
- gets the value of the dialog item. This determines the type of the item and
- does the obvious thing. For unknown items, returns 0.
- ----------------------------------------------------------------------------------------*/
-
- long ZDialog::GetValue( const short item )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & ctrlItem ) == ctrlItem )
- return GetControlValue(( ControlHandle ) itemHand );
-
- if (( itemType & editText ) == editText )
- {
- long value;
- Str255 iText;
-
- GetDialogItemText( itemHand, iText );
- StringToNum( iText, &value );
-
- return value;
- }
-
- return 0;
- }
-
-
- /*-----------------------------*** GETVALUEASTEXT ***---------------------------------*/
- /*
- get text of item, or if control, convert value to string first (complementary function to
- GetValue().
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::GetValueAsText( const short item, Str255 aStr )
- {
- short iType;
- Handle iHand;
- Rect iBox;
- unsigned short f;
- TEHandle th;
- long mx;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
-
- if ( iType & ( statText | editText ))
- {
- // if this is an edit field with the password flag set, return the text
- // from the mirror instead of the visible field.
-
- if ( iType & editText )
- {
- GetEditFieldInfo( item, &f, (long*) &th, &mx );
-
- if (( f & editFieldHCMirrorAlloc ) && ( th != NULL ))
- {
- GetDialogItemText(( Handle ) th, aStr );
- return;
- }
- }
-
- GetDialogItemText( iHand, aStr );
- }
- else
- {
- if ( iType & ctrlItem )
- {
- long v = GetValue( item );
-
- NumToString( v, aStr );
- }
- }
- }
-
-
- /*----------------------------*** GETVALUEASFLOAT ***---------------------------------*/
- /*
- get text of item, then convert it to a floating point number. This is useful to get real
- numbers from editable text fields, etc.
- ----------------------------------------------------------------------------------------*/
-
- float ZDialog::GetValueAsFloat( const short item )
- {
- Str255 itxt;
- decimal d;
- short vp, ix = 1;
-
- GetValueAsText( item, itxt );
-
- // make sure it can be read as a null-terminated string
-
- itxt[itxt[0] + 1 ] = 0;
-
- str2dec((const char*) itxt, &ix, &d, &vp);
- return dec2f( &d );
- }
-
-
- /*-----------------------------*** GETITEMBOUNDS ***----------------------------------*/
- /*
- get rect of item
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::GetItemBounds( const short item, Rect* bounds )
- {
- short iType;
- Handle iHand;
-
- GetDialogItem( macWindow, item, &iType, &iHand, bounds );
- }
-
-
- /*--------------------------------*** FINDITEM ***------------------------------------*/
- /*
- find the item under the mouse point (local coordinates), 0 if no item there
- ----------------------------------------------------------------------------------------*/
-
- short ZDialog::FindItem( const Point localMouse )
- {
- return ( FindDialogItem( macWindow, localMouse ) + 1);
- }
-
-
- /*------------------------------*** HILITEITEM ***------------------------------------*/
- /*
- allows controls to be hilited or dimmed
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::HiliteItem(const short item, const short state)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & ctrlItem ) == ctrlItem )
- {
- HiliteControl(( ControlHandle ) itemHand, state );
-
- if ( item == ok )
- OutlineDefaultItem();
- }
- else
- {
- if ( itemType & editText )
- SelectItem( item );
- }
- }
-
-
- /*-------------------------------*** HIDEITEM ***-------------------------------------*/
- /*
- hides the item entirely
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::HideItem( const short item )
- {
- HideDialogItem( macWindow, item );
- }
-
-
- /*-------------------------------*** SHOWITEM ***-------------------------------------*/
- /*
- re-shows a hidden item
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ShowItem( const short item )
- {
- ShowDialogItem( macWindow, item );
- }
-
-
- /*------------------------------*** ENABLEITEM ***------------------------------------*/
- /*
- enables a dialog item. If a control, it is undimmed. If static text, it is made into an
- editable field and undimmed. This can also be used to enable entire groups of controls
- by passing the negative of the group ID. Also, pass 0 to enable everything.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::EnableItem( const short item )
- {
- if ( item <= 0 )
- {
- // this is a group ID so find all controls in the group and enable them.
-
- short iType, i = CountDITL( macWindow );
- Handle iHand;
- Rect iBox;
- short mask;
-
- if ( item == 0 )
- mask = 0;
- else
- mask = 0xFF;
-
- while( i )
- {
- GetDialogItem( macWindow, i, &iType, &iHand, &iBox );
-
- if ((( iType & ctrlItem ) == ctrlItem ) && (((*dItemInfo)[i - 1].groupID & mask ) == -item ))
- {
- // pop the state history:
-
- Boolean state = (*dItemInfo)[i - 1].minValue & 1;
- (*dItemInfo)[i - 1].minValue >>= 1;
-
- HiliteItem( i, state? 255 : 0 );
- }
- i--;
- }
- }
- else
- {
- short iType = GetItemType( item ) & 0x7F;
-
- if ( iType & ctrlItem )
- HiliteItem( item, 0 );
- else
- {
- // if this is really a disabled edit field, re-enable it
-
- unsigned short iFlags;
- long min, max;
-
- GetEditFieldInfo( item, &iFlags, &min, &max );
-
- if (( iType == statText ) && ( iFlags & editFieldIsDisabled ))
- {
- // this is a disabled edit field really, so convert it back to an edit field,
- // clear the disable flag we are keeping and redraw the item.
-
- Handle iHand;
- Rect iBox;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
- iType = ( iType & 0x80 ) | editText;
- SetDialogItem( macWindow, item, iType, iHand, &iBox );
-
- // clear the private disable flag:
-
- iFlags &= ~editFieldIsDisabled;
- SetEditFieldInfo( item, iFlags, min, max );
- DrawOneItem( item );
- }
- }
- }
- }
-
-
- /*-----------------------------*** DISABLEITEM ***------------------------------------*/
- /*
- disables an item. If a control, the control is dimmed. If an edit field, it is converted
- to static text and drawn greyed out (dimmed). This also allows all controls in a group
- to be disabled at once- simply pass the negative of the group ID in. You can disable
- everything by passing 0. Note that the state history of items is stacked to a max depth
- of 32- EnableItem/DisableItem should be used in pairs when used for groups.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DisableItem( const short item )
- {
- if ( item <= 0 )
- {
- // this is a group ID so find all controls in the group and disable them. We record
- // their existing state in the <minValue> field of the item info so we can restore
- // it in EnableItem. n.b. since the group ID has slightly different meanings in the context
- // of radio buttons or groups of controls in general, to avoid problems in certain situ-
- // ations, we only compare the lower 8 bits of the ID. This it is possible to set up
- // groups that dim as a group, but interact slightly differently if desired.
-
- short iType, i = CountDITL( macWindow );
- Handle iHand;
- Rect iBox;
- short mask;
-
- if ( item == 0 )
- mask = 0;
- else
- mask = 0xFF;
-
- while( i )
- {
- GetDialogItem( macWindow, i, &iType, &iHand, &iBox );
-
- if ((( iType & ctrlItem ) == ctrlItem ) && (((*dItemInfo)[i - 1].groupID & mask ) == -item ))
- {
- // push the state history:
-
- (*dItemInfo)[i - 1].minValue <<= 1;
- (*dItemInfo)[i - 1].minValue |= ((*(ControlHandle) iHand)->contrlHilite == 255 )? 1 : 0;
- HiliteItem( i, 255 );
- }
-
- i--;
- }
- }
- else
- {
- short iType = GetItemType( item ) & 0x7F;
-
- if ( iType & ctrlItem )
- HiliteItem( item, 255 );
- else
- {
- // if this is an edit field, we disable it by converting it to static text and
- // setting a flag in the private field info. When redrawn, the text will be drawn
- // greyed out and the border in light grey.
-
- if ( iType == editText )
- {
- // one difficulty- if the edit field is the current one, we need to move the
- // hilite to another field otherwise strange effects will result which we don't
- // want.
-
- DialogPeek dp = (DialogPeek) macWindow;
- Handle iHand;
- Rect iBox;
-
- if ( dp->editField == ( item - 1 ))
- Type( TAB_KEY, 0 );
-
- // now convert it to static:
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
- iType = ( iType & 0x80 ) | statText;
- SetDialogItem( macWindow, item, iType, iHand, &iBox );
-
- // set the disable flag in the private data for the field
-
- unsigned short iFlags;
- long min, max;
-
- GetEditFieldInfo( item, &iFlags, &min, &max );
- iFlags |= editFieldIsDisabled;
- SetEditFieldInfo( item, iFlags, min, max );
-
- // now redraw the item to show it in its disabled state. The standard
- // user item proc draws the disabled border fo such items.
-
- DrawOneItem( item );
- ZDialog::DrawUserItem( item );
- }
- }
- }
- }
-
-
- /*--------------------------*** SETEDITFIELDINFO ***----------------------------------*/
- /*
- sets additional info about an edit field- for example you can set a field to only accept
- numbers, etc. The flags are a bitfield- you should generally take care to only change
- bits you need to and leave others untouched. Some combinations of bits are not allowed.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetEditFieldInfo( const short item, unsigned short iFlags, long iMin, long iMax )
- {
- DItemInfo di;
-
- // if the "password field" flag is set, create a mirror TEHandle for the field
- // if there isn't one already. Under no circumstances change the alloc flag- you can read
- // it to determine if <min> should be interpreted as a TEHandle, but never change it. YHBW!
-
- if (( iFlags & ( editFieldHiddenChars + editFieldHCMirrorAlloc )) == editFieldHiddenChars )
- {
- Rect invR = { 10000, 10000, 10020, 10100 };
- di.mirrorTE = TENew( &invR, &invR );
-
- iFlags |= editFieldHCMirrorAlloc;
- }
- else
- di.minValue = iMin;
-
- di.flags = iFlags;
- di.maxValue = iMax;
-
- (*dItemInfo)[item - 1] = di;
- }
-
-
- /*--------------------------*** GETEDITFIELDINFO ***----------------------------------*/
- /*
- returns info about an edit field as stored in the private data.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::GetEditFieldInfo( const short item, unsigned short* iFlags, long* iMin, long* iMax )
- {
- DItemInfo di = (*dItemInfo)[item - 1];
-
- *iFlags = di.flags;
-
- if ( iMin )
- *iMin = di.minValue;
-
- if ( iMax )
- *iMax = di.maxValue;
- }
-
-
- /*----------------------------*** SETITEMTITLE ***------------------------------------*/
- /*
- allows titles of control items to be changed programmatically
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetItemTitle( const short item, Str255 title )
- {
- short iType;
- Handle iHand;
- Rect iBox;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
-
- if ( iType & ctrlItem )
- SetControlTitle((ControlHandle) iHand, title );
- }
-
-
- /*-----------------------------*** SELECTITEM ***-------------------------------------*/
- /*
- if the item is an edit field, this sets it as the current one and selects all the text.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SelectItem( const short item )
- {
- if (( GetItemType( item ) & 0x7F ) == editText )
- {
- ZGrafState zg;
-
- if (((DialogPeek) macWindow )->textH )
- {
- SetTEItemDataFromIctb( ((DialogPeek) macWindow )->editField + 1 , TRUE );
- TEDeactivate( ((DialogPeek) macWindow )->textH );
- }
-
- SetTEItemDataFromIctb( item, TRUE );
- SelectDialogItemText( macWindow, item, 0, 32767 );
- }
- }
-
-
- /*-----------------------*** GETSELECTEDITEMINGROUP ***-------------------------------*/
- /*
- returns the item number of the "on" radio button in a group with the given ID. If the
- group represents other kinds of controls, this always returns 0. If a mixed group (i.e
- some radio buttons plus others) this will return the radio button that's on, or 0 if
- none are. This ignores the enabled state of the group or items.
- ----------------------------------------------------------------------------------------*/
-
- short ZDialog::GetSelectedItemInGroup( const short groupID )
- {
- short iType, i = CountDITL( macWindow );
- Handle iHand;
- Rect iBox;
-
- while( i )
- {
- GetDialogItem( macWindow, i, &iType, &iHand, &iBox );
-
- if ((( iType & radCtrl ) == radCtrl ) &&
- ((*dItemInfo)[ i - 1 ].groupID == groupID ) &&
- GetControlValue((ControlHandle) iHand ) != 0 )
- return i;
-
- i--;
- }
-
- return 0;
- }
-
-
-
- /*--------------------------*** OUTLINEDEFAULTITEM ***--------------------------------*/
- /*
- draws the bold border around the item number 1 in the dialog
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::OutlineDefaultItem()
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, ok, &itemType, &itemHand, &itemBox );
-
- // check that this item is a button
-
- if ( itemType & ( ctrlItem + btnCtrl ))
- {
- Focus();
-
- InsetRect( &itemBox, -4, -4 );
- PenNormal();
- PenSize( 3, 3 );
-
- // if button disabled, draw outline in grey
-
- if ((*(ControlHandle) itemHand )->contrlHilite == 255 )
- {
- AuxWinHandle awH;
-
- if ( IsColourPort( macWindow ) && GetAuxWin( macWindow, &awH ))
- {
- RGBColor midGrey = { 0x7F7F, 0x7F7F, 0x7F7F };
- RGBForeColor( &midGrey );
- }
- else
- PenPat( &qd.gray );
- }
- else
- ForeColor( blackColor );
-
- FrameRoundRect( &itemBox, 16, 16 );
- PenNormal();
- ForeColor( blackColor );
- }
- }
-
-
- /*-----------------------------*** HASEDITFIELDS ***----------------------------------*/
- /*
-
- returns TRUE if this dialog has any edit fields. Used to determine if Edit commands are
- enabled or not.
-
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::HasEditFields()
- {
- // returns TRUE if this dialog has at least one edit field. Use to enable
- // the edit menu.
-
- short itemType, item;
- Handle itemHand;
- Rect itemBox;
- Boolean hasEF = FALSE;
-
- item = CountDITL( macWindow );
-
- while(item)
- {
- GetDialogItem( macWindow, item--, &itemType, &itemHand, &itemBox );
-
- if (( itemType & 0x7F ) == editText &&
- ( itemBox.left < 8192 ))
- {
- hasEF = TRUE;
- break;
- }
- }
-
- return hasEF;
- }
-
-
- /*-----------------------------*** SETUPRADIOGROUPS ***-------------------------------*/
- /*
- This builds the array of radio button groups so that the click handler can correctly
- manage them. This is done very easily- in your DITL resource, add the group ID to the
- button title, separated by a double slash- e.g. My Button//1. This function strips the
- extra characters from the name, so you never see them. Groups start at ID = 1, and
- obviously buttons with the same group ID operate as a set. If you do not extend the title
- of a group button in this way, it will operate in the normal way- i.e. not very well.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetUpRadioGroups( short fromItemNo )
- {
- short iType, groupID;
- Boolean iDefault;
- Handle iHand;
- Rect iBox;
- long tMin, tMax;
- unsigned short tFlags;
- Str255 cTitle;
-
- // scan through looking for buttons and fields (which are also set up here). We scan
- // backwards for convenience, so to work for the extension case, we stop once we reach
- // <fromItemNo> + 1, which by default is 0.
-
- short iCount = CountDITL( macWindow );
-
- if ( iCount > fromItemNo )
- {
- do
- {
- GetDialogItem( macWindow, iCount, &iType, &iHand, &iBox );
-
- // is this item a radio button or other control? We permit buttons and checkboxes
- // to have a group ID as well- this can be used to disable or enable sets of
- // related buttons with one call. The group ID does not affect clicking the item
- // except for radio buttons.
-
- if ( iType & ctrlItem )
- {
- // get the title of the button
-
- GetControlTitle((ControlHandle) iHand, cTitle );
-
- // parse the title looking for a double slash followed by a number. This
- // is returned in groupID, and the title is stripped of the extra chars.
-
- ParseRButtonTitle( cTitle, &groupID, &iDefault );
-
- // set up the entry in the dialog item info table
-
- (*dItemInfo)[iCount - 1].groupID = groupID;
-
- // set the button's name to eliminate the grouping info
-
- SetControlTitle((ControlHandle) iHand, cTitle );
-
- // if this is the default button, set it ON
-
- if ( iDefault )
- SetControlValue((ControlHandle) iHand, 1 );
- }
- else
- {
- // set up info for edit fields from formatted resource string:
-
- if (( iType & 0x7F ) == editText )
- {
- GetDialogItemText( iHand, cTitle );
- ParseEditFieldInfo( cTitle, &tFlags, &tMin, &tMax );
- SetEditFieldInfo( iCount, tFlags, tMin, tMax );
- SetDialogItemText( iHand, cTitle );
- }
- }
- }
- while( --iCount > fromItemNo );
- }
- }
-
-
- /*---------------------------*** PARSERBUTTONTITLE ***--------------------------------*/
- /*
- Finds any group ID "buried" in the button name. This modifies the input string so that
- the extra characters are removed.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ParseRButtonTitle( Str255 buttonTitle, short* groupID, Boolean* isDefault )
- {
- register char cc = 1;
- long gID = 0;
- Str15 subStr;
-
- *groupID = 0; // in case we find nothing at all
- *isDefault = FALSE;
-
- // scan the string looking for two consecutive forward slashes:
-
- do
- {
- if ((buttonTitle[cc] == '/') && (buttonTitle[cc + 1] == '/'))
- {
- // found two consecutive slashes- now copy the rest of the string into
- // subStr.
-
- subStr[0] = buttonTitle[0] - cc - 1; // length of remainder of string
- if (subStr[0])
- {
- BlockMoveData(&buttonTitle[cc + 2], &subStr[1], subStr[0]);
-
- // look to see if this is the default button in the group. This is indicated
- // by the ID number being followed by a '*' character.
-
- if ( subStr[subStr[0]] == '*' )
- {
- *isDefault = TRUE;
-
- // remove char from string
-
- subStr[0]--;
- }
- else
- *isDefault = FALSE;
-
- // convert substring to a number. Note that results are unpredictable if
- // the string does not have a pure number following the two slashes.
- // e.g. "My Button//hello" will certainly not work!
-
- StringToNum( subStr, &gID );
-
- // shorten original string by the amount needed to remove extra
-
- buttonTitle[0] = cc - 1;
- *groupID = LoWord( gID );
-
- break;
- }
- }
- }
- while( ++cc <= buttonTitle[0] );
- }
-
-
- /*------------------------*** HANDLERBUTTONGROUPCLICK ***-----------------------------*/
- /*
- turns off the buttons in the same group as this item, then turns this one on.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::HandleRButtonGroupClick( const short item )
- {
- // <item> is already known to be a radio button, so find its "groupies" and turn them
- // all off. Then turn this one on.
-
- short groupID, tIndex, gIndex, iType, targetGroup;
-
- gIndex = CountDITL( macWindow );
- targetGroup = (*dItemInfo)[item -1].groupID;
-
- // if the target group is 0, do nothing, since user elected to handle these buttons
- // on his own- silly beggar!
-
- if ( targetGroup > 0 )
- {
- for( tIndex = 1; tIndex <= gIndex; tIndex++ )
- {
- iType = GetItemType( tIndex ) & 0x7F;
-
- if ( iType == ( ctrlItem + radCtrl ))
- {
- groupID = (*dItemInfo)[tIndex -1].groupID;
-
- // if this is in our target group, turn it off unless it's the
- // one that was just hit
-
- if ( groupID == targetGroup )
- {
- if ( tIndex == item )
- SetValue( tIndex, 1 );
- else
- SetValue( tIndex, 0 );
- }
- }
- }
- }
- }
-
-
- /*-------------------------*** SETTEITEMDATAFROMICTB ***------------------------------*/
- /*
- sets the TextEdit record that is handling the item to the relevant parameters in the
- associated 'ictb' resource. We made a copy of this resource when the dialog was opened.
- WARNING: ensure that the item is an edit text field before calling this!
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetTEItemDataFromIctb( const short teItem, Boolean applyChanges )
- {
- if ( macWindow && IsColourPort( macWindow ) && ictb )
- {
- // there is an ictb, so see if this item has a special entry:
-
- TEHandle te;
- ictbItemEntry ie;
- TextStyle tsRec;
-
- te = ((DialogPeek) macWindow)->textH;
- ie = (*ictb)[ teItem - 1 ];
-
- if ( ie.iData != 0 &&
- ie.iOffset != 0 )
- {
- // yes, there is a special setting for this item- what is it?
-
- ictbTablePtr tp;
-
- HLock((Handle) ictb );
- tp = ( ictbTablePtr ) ((Ptr) *ictb + ie.iOffset );
-
- // tp is now pointing at the text table for the item. Using this table,
- // we need to set up a TEStyle record and pass it to TextEdit.
-
- // the font is either already known or can be looked up via its name
-
- if ( ie.iData & fFamChange )
- {
- if ( ie.iData & fIsFNameOffset )
- {
- // need to look up the font via the name table. In this case
- // txtFont contains the offset to the font's name
-
- GetFNum((unsigned char*) *ictb + tp->txtFont , &tsRec.tsFont);
- }
- else
- tsRec.tsFont = tp->txtFont;
- }
- else
- tsRec.tsFont = macWindow->txFont;
-
- // set simple fields
-
- if ( ie.iData & fFaceChange )
- tsRec.tsFace = tp->txtFace;
- else
- tsRec.tsFace = macWindow->txFace;
-
- if ( ie.iData & fSizeChange )
- tsRec.tsSize = tp->txtSize;
- else
- tsRec.tsSize = macWindow->txSize;
-
- // set the colours of the port
-
- if ( applyChanges )
- {
- if ( ie.iData & fFColourChange )
- RGBForeColor( &tp->txtFColour );
-
- if ( ie.iData & fBColourChange )
- RGBBackColor( &tp->txtBColour );
- }
- HUnlock((Handle) ictb );
- }
- else
- {
- tsRec.tsFace = macWindow->txFace;
- tsRec.tsFont = macWindow->txFont;
- tsRec.tsSize = macWindow->txSize;
-
- // reset the default colours as well
-
- if ( applyChanges )
- {
- AuxWinHandle aw;
-
- if ( GetAuxWin( macWindow, &aw ))
- {
- RGBColor rgb = (*(*aw)->awCTable)->ctTable[0].rgb;
-
- RGBBackColor( &rgb );
- ForeColor( blackColor );
- }
- }
- }
-
- (*te)->txFont = tsRec.tsFont;
- (*te)->txFace = tsRec.tsFace;
- (*te)->txSize = tsRec.tsSize;
-
- TextFont( tsRec.tsFont );
- TextFace( tsRec.tsFace );
- TextSize( tsRec.tsSize );
-
- // note: at this point, the lineHeight of the teRec should be calculated for the new
- // font. The Dialog Manager fails to do this, and the results are poor text alignment
- // and jumpiness in fields. MacZoop hereby fixes this bug so you no longer need a
- // workaround:
-
- FontInfo fi;
-
- GetFontInfo( &fi );
- (*te)->lineHeight = fi.ascent + fi.descent + fi.leading;
- (*te)->fontAscent = fi.ascent;
-
- TECalText( te );
- }
- }
-
-
- /*--------------------------*** ADDGREYSCALEEFFECTS ***-------------------------------*/
- /*
- adds 3D effect borders to edit text items
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::AddGreyscaleEffects()
- {
- short n, iType;
- Handle iHand;
- Rect r;
- unsigned short iFlags;
-
- if ( IsColourPort( macWindow ))
- {
- SetDefaultColours();
- n = CountDITL( macWindow );
-
- while( n )
- {
- GetEditFieldInfo( n, &iFlags );
- GetDialogItem( macWindow, n--, &iType, &iHand, &r );
-
- if ((( iType & 0x7F ) == editText ) ||
- ((( iType & 0x7F ) == statText ) && ( iFlags & editFieldIsDisabled )))
- {
- InsetRect( &r, -3, -3 );
- FrameGrayRect( &r );
- }
- }
- }
- }
-
-
- /*-------------------------------*** KEYISLEGAL ***-----------------------------------*/
- /*
- returns TRUE if the key character is permitted in the targetted field according to its
- info flags (set by SetEditFieldInfo). This is called by Type().
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::KeyIsLegal( char* theKey, const short targetItem )
- {
- Boolean keyLegal = TRUE;
- Boolean numeric;
- unsigned short iFlags;
- short iType;
- char k = *theKey;
-
- iType = GetItemType( targetItem ) & 0x7F;
-
- if ( iType == editText )
- {
- GetEditFieldInfo( targetItem, &iFlags );
-
- // if flags are all zero, this is a normal field and all chars are allowed,
- // otherwise we're limited to certain sets of characters according to exactly
- // which flags are set.
-
- if ( iFlags )
- {
- keyLegal = FALSE;
- numeric = ( k >= '0' && k <= '9' );
-
- // alphabetic only eliminates all ascii chars below the @ symbol:
-
- if ( iFlags & editFieldAlphabeticOnly )
- keyLegal = ( k >= '@' || k < '0' );
-
- // signed integer allows only numbers and - sign
-
- if ( iFlags & editFieldSignedInteger )
- keyLegal = numeric || ( k == '-' );
-
- // signed float additionally allows decimal point
-
- if ( iFlags & editFieldSignedFloat )
- keyLegal = numeric || (k == '-' ) || ( k == '.' );
-
- // unsigned integer disallows - sign
-
- if ( iFlags & editFieldUnsignedInteger )
- keyLegal = numeric;
-
- // unsigned float allows decimal point but not - sign
-
- if ( iFlags & editFieldUnsignedFloat )
- keyLegal = numeric || ( k == '.' );
-
- // these keys are always considered legal:
-
- keyLegal |= ( k == BACKSPACE_KEY ||
- k == UP_ARROW_KEY ||
- k == DOWN_ARROW_KEY ||
- k == LEFT_ARROW_KEY ||
- k == RIGHT_ARROW_KEY||
- k == RETURN_KEY ||
- k == ENTER_KEY ||
- k == ESCAPE_KEY );
-
- // password field? all chars permitted, but transmutes the character. Note that
- // this feature flag should not be used with any others set.
-
- if ( iFlags & editFieldHiddenChars )
- {
- // if not a control character, transmute to a bullet:
-
- if ( ! keyLegal )
- *theKey = '•';
-
- // all characters legal here
-
- keyLegal = TRUE;
- }
- }
- }
-
- return keyLegal;
- }
-
-
- /*----------------------------*** PASTEDATAISLEGAL ***--------------------------------*/
- /*
- if the clipboard contains text and the paste target is an edit field, this determines
- if the text is in a legal format according to the info stored for the field. This is used
- to enforce the field restrictions when pasting.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::PasteDataIsLegal( const short targetItem )
- {
- Boolean legalPaste;
- unsigned short iFlags;
- char* testStr;
- long tSize;
-
- legalPaste = ZDialog::CanPasteType();
-
- if ( legalPaste )
- {
- // get the flags for the target field. If zero, this is a normal field and all
- // text is valid, so there is no need to further test it.
-
- GetEditFieldInfo( targetItem, &iFlags );
-
- if ( iFlags )
- {
- // you can't paste into a password field, so if that flag's set, return FALSE
-
- if ( iFlags & editFieldHiddenChars )
- return FALSE;
-
- // in order to check the text, we need to obtain a copy of it
-
- Handle tx = gClipboard->GetData( 'TEXT' );
-
- if ( tx )
- {
- // to test the text, we scan through it and call KeyIsLegal() for each
- // character until it returns FALSE, indicating that a bad char was
- // found in the text.
-
- tSize = GetHandleSize( tx );
- HLock( tx );
- testStr = (char*) *tx;
-
- while( tSize )
- {
- if ( !KeyIsLegal( testStr, targetItem ))
- {
- legalPaste = FALSE;
- break;
- }
-
- testStr++;
- tSize--;
- }
-
- HUnlock( tx );
- DisposeHandle( tx );
- }
- else
- legalPaste = FALSE;
- }
- }
-
- return legalPaste;
- }
-
-
- /*---------------------------*** PARSEEDITFIELDINFO ***-------------------------------*/
- /*
- extracts set uyp flags and any min or max associated with a field. This is set in the
- resource using a specially formatted string similar to the way button groups work.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ParseEditFieldInfo( Str255 efText, unsigned short* efFlags, long* min, long* max )
- {
- register char cc = 1, dc;
- unsigned char stPart, ssLen;
- long temp;
- Str15 subStr;
-
- *efFlags = 0;
- *min = 0;
- *max = 0;
-
- do
- {
- // scan forward looking for two forward slashes
-
- if (( efText[cc] == '/' ) && ( efText[cc + 1] == '/' ))
- {
- // found two consecutive slashes- note the length of the info and scan for
- // delimiters
-
- stPart = 0;
- ssLen = efText[0] - cc + 1;
-
- // string will consist of up to three numbers, separated by commas.
- // the first number is the flags field, the second (optional) the
- // min limit, and the third (optional) the max limit
-
- cc += 2;
- dc = cc;
-
- while( dc <= efText[0] )
- {
- // scan for the next comma or end of string:
-
- if (( dc >= efText[0] ) || ( efText[ dc + 1 ] == ',' ))
- {
- // found a segment- extract it into subStr and convert to number
-
- subStr[0] = dc - cc + 1;
- BlockMoveData( &efText[cc], &subStr[1], dc - cc + 1 );
- StringToNum( subStr, &temp );
-
- // assign it to the relevant parameter
-
- switch( stPart )
- {
- case 0:
- *efFlags = temp;
- break;
-
- case 1:
- *min = temp;
- break;
-
- case 2:
- *max = temp;
- break;
- }
-
- stPart++;
- cc = dc + 2;
- dc = cc - 1;
- }
-
- dc++;
- }
-
- // remove extra data from string:
-
- efText[0] -= ssLen;
- break;
- }
- }
- while( ++cc <= efText[0] );
- }
-
-
- /*---------------------------*** APPENDITEMSTODIALOG ***------------------------------*/
- /*
- extends the dialog by appending another 'DITL' resource to it. This calls AppendDITL but
- has the additional advantage of allowing our private radio groups and edit-field info
- stuff to work correctly.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::AppendItemsToDialog( const short ditlID, DITLMethod apMethod )
- {
- Handle ditH;
- short numAdded, items, existItems, i;
- Rect ir, iBounds;
-
- existItems = CountDITL( macWindow );
-
- FailNILRes( ditH = GetResource( 'DITL', ditlID ));
- AppendDITL( macWindow, ditH, apMethod );
- ReleaseResource( ditH );
-
- items = CountDITL( macWindow );
- numAdded = items - existItems;
-
- // extend the private data by this many entries
-
- long pdSize = GetHandleSize((Handle) dItemInfo );
- pdSize += ( sizeof( DItemInfo ) * numAdded );
- SetHandleSize((Handle) dItemInfo, pdSize );
- FailMemError();
-
- for( i = existItems; i < items; i++ )
- {
- (*dItemInfo)[i].flags = 0;
- (*dItemInfo)[i].minValue = 0;
- (*dItemInfo)[i].maxValue = 0;
-
- GetItemBounds( i + 1, &ir );
-
- if ( i == existItems )
- iBounds = ir;
- else
- UnionRect( &ir, &iBounds, &iBounds );
- }
- // now we need to set up these additional entries with group or field data
-
- SetUpUserItems( existItems );
- SetUpRadioGroups( existItems );
-
- InsetRect( &iBounds, -4, -4 );
- InvalRect( &iBounds );
- }
-
-
- /*---------------------------*** REMOVEAPPENDEDITEMS ***------------------------------*/
- /*
- removes any extra items added by the above routine.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::RemoveAppendedItems()
- {
- short numToRemove, items, i;
- Rect iBounds, ir;
-
- items = CountDITL( macWindow );
- numToRemove = items - baseItems;
-
- if ( numToRemove > 0 )
- {
- for( i = baseItems + 1; i <= items; i++ )
- {
- GetItemBounds( i, &ir );
-
- if ( i == baseItems + 1 )
- iBounds = ir;
- else
- UnionRect( &ir, &iBounds, &iBounds );
- }
-
- ShortenDITL( macWindow, numToRemove );
-
- // erase the area encompassed by the items (this step is necessary
- // if extra 3D effects are present, since they draw outside the items'
- // borders.
-
- InsetRect( &iBounds , -4, -4 );
- EraseRect( &iBounds );
-
- // remove the extra data from the private handle too
-
- long pdSize = GetHandleSize((Handle) dItemInfo );
- pdSize -= ( sizeof( DItemInfo ) * numToRemove );
- SetHandleSize((Handle) dItemInfo, pdSize );
- FailMemError();
- }
- }
-
-
- /*------------------------------*** WRITETOSTREAM ***---------------------------------*/
- /*
- store dialog in the stream. note this does NOT call ZWindow's WriteToStream method
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::WriteToStream( ZStream* aStream )
- {
- #if _MACZOOP_STREAMS
- ZCommander::WriteToStream( aStream );
-
- // save window state info to the stream. This includes its position, title, visible
- // and floating flags, ID, etc, etc.
-
- short h, v;
- Str255 title;
-
- // write essential data stored in <macWindow> first...
-
- aStream->WriteRect( &macWindow->portRect );
-
- aStream->WriteChar( IsVisible());
- aStream->WriteShort( GetWVariant( macWindow ));
- GetName( title );
- aStream->WriteString( title );
- aStream->WriteChar(((WindowPeek) macWindow )->goAwayFlag );
-
- // now we need to stream the items list. For simplicity, what is actually streamed
- // is the DITL handle for the dialog, which specifies all items. However, in order
- // to recreate the dialog from this handle, it is necessary to clear the "place holder"
- // fields to NULL so that NewDialog recreates the various item handles. This is a tad
- // tedious, but unfortunately necessary.
-
- Handle ditl = ((DialogPeek) macWindow )->items;
-
- FailOSErr( HandToHand( &ditl ));
-
- ClearDITLPlaceHolders( ditl );
- aStream->WriteHandle( ditl );
- DisposeHandle( ditl );
-
- // write grafport state
-
- aStream->WriteGrafPort( macWindow );
-
- // write window colour table, if there is one
-
- AuxWinHandle awH;
-
- if ( GetAuxWin( macWindow, &awH ))
- aStream->WriteHandle((Handle) (*awH)->awCTable );
- else
- aStream->WriteHandle( NULL );
-
- // write global window position...
-
- GetGlobalPosition( &h, &v );
- aStream->WriteShort( h );
- aStream->WriteShort( v );
-
- // write various window data members...
-
- aStream->WriteRect( &sizeRect );
- aStream->WriteShort( windID );
- aStream->WriteChar( isNamed );
- aStream->WriteChar( stationeryFile );
- aStream->WriteData((Ptr) &macFile, sizeof( FSSpec ));
- aStream->WriteLong((long) macFType );
- aStream->WriteChar( printable );
- aStream->WriteChar( floating );
- aStream->WriteChar( disableAutoClose );
- aStream->WriteRect( &zoomSource );
-
- // finally, we must write the states and values of all of the dialog items, in order that
- // we can restore the dialog EXACTLY when it is streamed back in. The basic DITL will have
- // established the groups for buttons, etc, but still the contents and values of text and
- // controls is not known.
-
- aStream->WriteHandle((Handle) dItemInfo );
- aStream->WriteHandle((Handle) ictb );
-
- for( h = 1; h <= CountDITL( macWindow ); h++ )
- {
- v = GetItemType( h ) & 0x7F;
-
- switch( v )
- {
- case editText:
- case statText:
- // text items are written as strings
- GetValueAsText( h, title );
- aStream->WriteString( title );
- break;
-
- case userItem:
- case picItem:
- case iconItem:
- // these items are currently not streamed- the correct resources must be present.
- // This may change later on [TO DO]
- break;
-
- default:
- // controls' values are written as longs, control's enable state as a char [TO DO]
-
- aStream->WriteLong( GetValue( h ));
- break;
- }
- }
- #endif
- }
-
-
- /*------------------------------*** READFROMSTREAM ***--------------------------------*/
- /*
- construct dialog from the stream
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ReadFromStream( ZStream* aStream )
- {
- #if _MACZOOP_STREAMS
- ZCommander::ReadFromStream( aStream );
-
- Rect pr;
- Boolean vis, goAway;
- short varCode, h, v;
- long dLen;
- Handle ditl;
- Str255 title;
-
- aStream->ReadRect( &pr );
- aStream->ReadChar((char*) &vis );
- aStream->ReadShort( &varCode );
- aStream->ReadString( title );
- aStream->ReadChar((char*) &goAway );
- aStream->ReadHandle( &ditl );
-
- FailNIL( ditl );
-
- // n.b. dialog assumes ownership of the items list handle
-
- MakeMacWindow( &pr, title, FALSE, varCode, goAway, ditl );
-
- // read rest of basic window parameters: font, colours, etc
-
- aStream->ReadGrafPort( macWindow );
-
- // read window colour table, which window becomes owner of
-
- WCTabHandle ct = NULL;
-
- aStream->ReadHandle((Handle*) &ct );
-
- if ( ct && gMacInfo.supportsColour )
- SetWinColor( macWindow, ct );
-
- aStream->ReadShort( &h );
- aStream->ReadShort( &v );
- MoveWindow( macWindow, h, v, FALSE );
-
- aStream->ReadRect( &sizeRect );
- aStream->ReadShort( &windID );
- aStream->ReadChar((char*) &isNamed );
- aStream->ReadChar((char*) &stationeryFile );
- dLen = sizeof( FSSpec );
- aStream->ReadData((Ptr) &macFile, &dLen );
- aStream->ReadLong((long*) &macFType );
- aStream->ReadChar((char*) &printable );
- aStream->ReadChar((char*) &floating );
- aStream->ReadChar((char*) &disableAutoClose );
- aStream->ReadRect( &zoomSource );
-
- // set up the local stuff...
-
- short item = CountDITL( macWindow );
- baseItems = item;
-
- FailNIL( dItemInfo = ( DItemInfoHdl ) NewHandleClear( sizeof( DItemInfo ) * item ));
-
- SetUpUserItems(); // install user item procs so we get callbacks
- SetUpRadioGroups();
-
- // read the handle which is a list of DItemInfo records- this restores group info and states,
- // though the above call is still needed to strip off control title grouping characters.
-
- DisposeHandle((Handle) dItemInfo );
- aStream->ReadHandle((Handle*) &dItemInfo );
- FailNIL( dItemInfo );
-
- aStream->ReadHandle((Handle*) &ictb );
-
- // finally, we must read the true states and values of all of the dialog items
-
- for( h = 1; h <= item; h++ )
- {
- v = GetItemType( h ) & 0x7F;
-
- switch( v )
- {
- case editText:
- case statText:
- // text items are strings
- aStream->ReadString( title );
- SetValue( h, title );
- break;
-
- case userItem:
- case picItem:
- case iconItem:
- // these items are currently not streamed- the correct resources must be present.
- break;
-
- default:
- // controls' values are longs
- aStream->ReadLong( &dLen );
- SetValue( h, dLen );
- break;
- }
- }
-
- SetUp(); // call user's set up method
- OutlineDefaultItem(); // set default button to ok button
-
- // register with window manager...
-
- gWindowManager->AddWindow( this );
- ResetAlertStage();
-
- if ( vis )
- Show();
- #endif
- }
-
-
- /*--------------------------*** CLEARDITLPLACEHOLDERS ***-----------------------------*/
- /*
- in order to stream a dialog's item list, the place holder fields must generally be
- cleared. This performs that on what is expected to be a COPY of the dialog items list.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ClearDITLPlaceHolders( Handle ditl )
- {
- FailNILParam( ditl );
- HLock( ditl );
-
- long dl = GetHandleSize( ditl );
- long off = 2;
- Ptr p = *ditl;
-
- while( off <= dl )
- {
- // clear place holder:
-
- *(long*)( p + off ) = 0;
-
- // calculate offset to next one. This is equal to 13 + the value
- // at 14 bytes from current place.
-
- off += 13;
- off += *( p + off ) + 1;
-
- // if that's an odd address, increment by one
-
- if ( off & 1 )
- off++;
- }
-
- HUnlock( ditl );
- }
-
-
- #pragma mark -
- /*--------------------------*** UserItemVectorProc ***--------------------------------*/
- /*
-
- This is used to vector user-item updates to the DrawUserItem method. Do not change this-
- override DrawUserItem instead.
-
- ----------------------------------------------------------------------------------------*/
-
- static pascal void UserItemVectorProc( DialogPtr theDialog, short item )
- {
- ZDialog* aZD = (ZDialog*) GetWRefCon( theDialog );
-
- if ( aZD )
- aZD->DrawUserItem( item );
- }
-
-
- /*-------------------------------*** REALTOSTRING ***---------------------------------*/
-
- void RealToString( const double num, Str255& str, short decPlaces )
- {
- decimal d;
- decform df;
-
- df.style = FIXEDDECIMAL;
- df.digits = decPlaces;
-
- num2dec( &df, num, &d );
- dec2str( &df, &d, (char*) &str[1] );
-
- // set length of pascal string by scanning until we reach null terminator
-
- str[0] = 0;
- while( str[++str[0]] );
- }
-
-
- /*-------------------------------*** FRAMEGRAYRECT ***---------------------------------*/
-
-
- void FrameGrayRect( Rect* aRect )
- {
- Rect globRect;
- GDHandle aDev;
- RGBColor aColour;
- RGBColor bColour;
-
- // frames a rectangle using two shades of gray so that the rectangle appears to
- // be recessed into a gray surface. This actually draws 1 pixel outside the
- // passed rectangle, so that normal FrameRect calls work as expected in addition.
-
- globRect = *aRect;
- LocalToGlobal( &topLeft( globRect ));
- LocalToGlobal( &botRight( globRect ));
- aDev = GetMaxDevice( &globRect );
-
- GetBackColor( &aColour );
- bColour.red = bColour.green = bColour.blue = 0xFFFF;
- GetGray( aDev, &aColour, &bColour );
-
- RGBForeColor( &bColour );
- MoveTo( aRect->left, aRect->bottom );
- LineTo( aRect->right, aRect->bottom );
- LineTo( aRect->right, aRect->top );
-
- bColour.red = bColour.green = bColour.blue = 0;
- GetGray( aDev, &aColour, &bColour );
- RGBForeColor( &bColour );
-
- Move( 0, -1 );
- LineTo( aRect->left - 1, aRect->top - 1 );
- LineTo( aRect->left - 1, aRect->bottom );
-
- ForeColor( blackColor );
- }
-
-
-
-